#!/usr/bin/python
# -*- coding: utf-8 -*-
# File: vstore.py
# Author: Tomás Vírseda
# License: GPL v3
# Description:  This is the Virtual Store class. It is like a layer
# between the real store and the application. It keeps a cache of
# opened reosurces and update them when neccesary.

from datetime import datetime
import gtk
from rdflib import Literal
from rdflib import URIRef

import vazaarlib.query
from vazaarlib.utils import get_logger
from vazaarlib.namespaces import *
from vazaarlib.vresource import VirtualResource

class VirtualStore():
    """
    This is the Virtual Store class. It is like a layer between the real
    store and the application. It keeps a cache of opened reosurces and
    update them when neccesary.

    Also it has methods to perform operations with resources like add,
    delete, get and update among others more specific.

    FIXME
    """

    #vstore = {}

    def __init__(self, app, ask):
        self.app = app
        self.store = self.app.store
        self.ask = ask
        self.log = get_logger('VStore')
        self.lastmodified = None
        self.cache = {}

    def add_triples(self, triples):
        self.store.add_triples(triples)

    def delete_triples(self, triples):
        self.store.delete_triples(triples)

    def add_resource(self, vresource):
        """ Add a new resource to store and cache:
            - Firstly, add it to cache, then to store
            - Update store's last modified date
        """
        subject = vresource.get_id()

        # caching resource
        #id = str(subject[9:])
        #self.cache[id] = vresource

        for predicate in vresource.prop:
            try:
                objects = vresource.prop[predicate]
                for object in objects:
                    self.store.add_triple(subject, predicate, object)
            except Exception, error:
                print "vstore:add_resource:", error

        self.store.do_commit() # store
        self.set_lastmodified() # set date


    def add_resource_property(self, id, property):
        self.set_lastmodified()
        pass


    def delete_resources(self, target_list):
        """Delete resource from cache and from knowledgement base
        """
        for idr in target_list:
            id = str(idr[9:])
            try:
                self.cache.pop(id)
            except:
                pass # it's possible that a resource isn't in the cache

        self.store.delete_resources(target_list)


    def get_last_modification_date(self, id):
        return self.ask.get_property(id, NAO['lastModified'])


    def get_virtual_resource(self, id_target):
        """
        Return a Virtual Resource from cache if exists. Otherway, a new
        Virtual Resource is built and added to cache
        """
        try:
            # return from cache
            id = str(id_target[9:])
            vres = self.cache[id]
            if vres is not None:
                return vres
        except:
            # get from store
            vres = VirtualResource()
            vres.set_id(id_target)
            propdict = self.ask.get_properties(id_target)
            vres.prop = propdict
            id = str(id_target[9:])
            self.cache[id] = vres
            return vres

    def del_resource_property(self, id, property):
        self.set_lastmodified()
        pass


    def upd_resource(self, id_target, vresource):
        self.set_lastmodified()
        pass


    def update_resource_property(self, s, p, o1, o2):
        try:
            id = str(s[9:])
            self.cache.pop(id)
        except:
            pass

        self.store.update_resource_property(s, p, o1, o2)

    def describe(self):
        pass
        """
        print "Num. Resources: %d" % len(self.cache)
        for vresource in self.cache:
            print "\tResource: %s (%d)" % (vresource, len(self.cache[vresource].metadata))
        """

    def set_lastmodified(self):
        """Set last modification date to Virtual Store"""

        self.lastmodified = datetime.now()


    def update_real_store(self):
        d1 = self.store.lastmodified
        d2 = self.lastmodified
        dt = d2 - d1
        if dt.seconds > 5:
            pass #print "Updating real store"


    def create_new_collection(self, title):
        # Create a new Collection
        now = str(datetime.now())[0:19]
        vcol = VirtualResource()
        vcol.set_id()
        header = []
        header.append((RDF.type, PIMO['Collection']))
        header.append((NIE['title'], Literal(title)))
        header.append((NAO['created'], Literal(str(now))))
        header.append((NAO['lastModified'], Literal(str(now))))
        vcol.set_metadata(header)
        self.add_resource(vcol)
        icon = self.app.gui.icons.get_icon_by_name('Collection-add.svg', 128, 128)
        self.app.gui.actions.notify('%s' % title, "A new collection was added to Vazaar</big>", icon)

    def unlink_resource_from_collection(self, col, id):
        triples = []
        subject = URIRef(col)
        predicate = NIE['hasLogicalPart']
        object = URIRef(id)
        triples.append((subject, predicate, object))
        self.delete_triples(triples)

    def link_resources_to_collections(self, collections, resources):
        try:
            triples = []
            predicate = URIRef(NIE['hasLogicalPart'])
            for collection in collections:
                subject =  URIRef(collection)
                for resource in resources:
                    object = URIRef(resource)
                    triples.append ((subject, predicate, object))
            self.add_triples(triples)
        except Exception, error:
            pass #print error
    """
    def update_resource_property(self, s, p, o1, o2):
        pass
    """
